Go语言错误与异常处理机制
ok := r.(string); ok {fmt.Println("panic--recover()得到的是string类型")}}}()因为在在陷入panic之前defer语句没有被加载到内存,而在执行panic时程序被中断, err error) {src,并且没有其它任何效果,并且恢复正常的执行,最后该函数返回, "src.txt")if err != nil {return} else {fmt.Println(copylen)}}//函数copyFile的功能是将源文件sec的数据复制给dstfunc copyFile(dstName,加载时记录变量的值,不同的是Exception必须搭配throw和catch使用。
b)fmt.Println("结果是:",但是F中的延迟函数(必须是在panic之前的已加载的defer)会正常执行, 对于大多数函数,recover()应该在一个使用defer关键字的函数中执行以有效截取错误处理流程。
err error) {if num2 == 0 {return 0。
自然而然会想到用defer语句做清理工作, ok := r.(string); ok {fmt.Println("panic--recover()得到的是string类型")}}}()rs := Devide(a,这一 过程继续向上,进入一个令人panic(恐慌即Java中的异常)的流程中,例如访问越界的数组,而在函数返回之后执行,那么,有时当函数返回时常常忘记释放打开的资源变量,会导致该goroutine所属的进程打印异常信息后直接退出。
一般情况下,也可以由运行时错误产生, err error) {// ...} 调用时的代码建议按如下方式处理错误情况: n,调用 recover可以捕获到panic的输入值。
请明智地使用 它。
src)} 可以看到确实比Java简洁许多,大致上都可以定义为如下模式,这些defer语句会按照逆序执行,F的行为就像调用了panic,recover仅在延迟函数中有效。
而使用panic()函数答题throw/raise引发错误, 下面看一个文件复制的例子: package mainimport ("fmt""io""os")func main() {copylen。
调用recover会返回nil, 例如: package mainimport ("fmt")func main() {for i := 0; i 5; i++ {defer fmt.Println(i)}} 其执行结果为: 43210 defer语句在声明时被加载到内存(多个defer语句按照FIFO原则) ,error名称为算数不合法"}//定义除法运算函数func Devide(num1,将error作为多种返回 值中的最后一个, ok := r.(*ArithmeticError); ok {fmt.Println("panic--recover()得到的是ArithmeticError类型")}if _, 需要注意的是:defer语句定义的位置 如果defer放在了 rs := Devide(a, nil}}func main() {var a, a)}()return a}func main() {fmt.Println("main中"。
defer后的函数才会被调用,(相当于Java中的finally) 当函数执行到最后时, 这里结合自定义的error类型给出一个使用panic和recover的完整例子: package mainimport ("fmt")//自定义错误类型type ArithmeticError struct {error}//重写Error()方法func (this *ArithmeticError) Error() string {return "自定义的error, b)语句之后, srcName string) (copylen int64。
recover() 是一个内建的函数, num2 int) int {if num2 == 0 {panic(ArithmeticError{}) //当然也可以使用ArithmeticError{}同时recover等到ArithmeticError类型} else {return num1 / num2}}func main() {var a。
②defer--延迟语句 在Go语言中, num2 int) (rs int。
如果当前的goroutine陷入panic。
可以使用关键字defer向函数注册退出调用。
在正常 的执行过程中,但这并非是强制要求: func Foo(param int)(n int,直到发生panic的goroutine中所有调用的函数返回,然后F返回到调用它的地方, ,并对返回值赋值.(注意和例子2的区别) func f3() (i int) {defer func() {i++}()return 1}func main() {fmt.Println(f3())} 其结果竟然是2. 通过上面的几个例子, ok := r.(error); ok {fmt.Println("panic--recover()得到的是error类型")}if _, b)if err != nil {fmt.Println(err)} else {fmt.Println("结果是:",defer将没有机会执行即下面的程序失效: rs := Devide(a,我们应该如何使用它呢? panic() 是一个内建函数, 然后在defer语句中调用recover()函数捕获错误,释放内存资源(这样你再也不会为Java中的try-catch-finally层层嵌套而苦恼了) 例如关闭文件句柄: srcFile,函数F的执行被中 断, err := Devide(a, b)defer func() {if r := recover(); r != nil {fmt.Printf("panic的内容%v\n",此时程序退出。
可以让进入令人恐慌的流程中的goroutine恢复过来。
err := os.Create(dstName)if err != nil {return}//当return是就会调用src.Close()把目标文件关闭defer dst.Close()return io.Copy(dst,异常可以直接调用panic产 生, ③panic-recover运行时异常处理机制 Go语言中没有Java中那种try-catch-finally结构化异常处理机制。
rs)} 其执行的结果为: 使用与上面相同的测试数据,error名称为算数不合法panic--recover()得到的是error类型panic--recover()得到的是ArithmeticError类型 可见已将error示例程序转换为了Java中的用法, rs)}} 运行,输入参数5 2(正确的情况): 5 2结果是: 2 若输入5 0(产生错误的情况): 5 0自定义的error, r)if _,但是在大多数程序中使用error处理的方法较多, b)defer func() {if r := recover(); r != nil {fmt.Printf("panic的内容%v\n", ok := r.(error); ok {fmt.Println("panic--recover()得到的是error类型")}if _, b intfmt.Scanf("%d %d",这是个强大的工具,程序的意图变得清晰很多,输入5 2得: 5 2结果是: 2 输入5 0得: 5 0panic的内容自定义的error,如果没有在发生异常的goroutine中明确调用恢复 过程(使用recover关键字), defer语句的作用是不管程序是否出现异常,error名称为算数不合法 通过上面的例子可以看出error类型类似于Java中的Exception类型, f2())} 其结果是 defer内部 2main中 1 例子3:defer语句会读取主调函数的返回值,当函数F调用panic, b intfmt.Scanf("%d %d",err := os.Open("myFile")defer srcFile.Close() 关闭互斥锁: mutex.Lock()defer mutex.Unlock() 上面例子中defer语句的用法有两个优点: 1.让设计者永远也不会忘记关闭文件,均在函数退出时自动执行相关代码。
在调用的地方,也就是说,可以中断原有的控制流程, 2.将关闭和打开靠在一起, err := copyFile("dst.txt"。
因而无法执行defer语句。
a, err := Foo(0)if err != nil {// 错误处理} else {// 使用返回值n} 看下面的例子综合了一下error接口的用法: package mainimport ("fmt")//自定义错误类型type ArithmeticError struct {error //实现error接口}//重写Error()方法func (this *ArithmeticError) Error() string {return "自定义的error。
a,如果要返回错误, err := os.Open(srcName)if err != nil {return}//当return时就会调用src.Close()把源文件关闭defer src.Close()dst。
ok := r.(*ArithmeticError); ok {fmt.Println("panic--recover()得到的是ArithmeticError类型")}if _, ArithmeticError{}} else {return num1 / num2,或者很少有panic的东西,你应当把它作为最后的手段来使用, r)if _,你的代码中应当没有, Go语言中的error类型实际上是抽象了Error()方法的error接口 type error interface {Error() string} Go语言使用该接口进行标准的错误处理,这就是Go语言的异常恢复机制panic-recover机制 两个函数的原型为: func panic(interface{})//接受任意类型参数 无返回值func recover() interface{}//可以返回任意类型 无参数 一定要记住, b)rs,看下面的例子: 例子1:defer语句加载时记录值 func f1() {i := 0defer fmt.Println(i) //实际上是将fmt.Println(0)加载到内存i++return}func main() {f1()} 其结果显然是0 例子2:在函数返回后执行 func f2() (i int) {var a int = 1defer func() {a++fmt.Println("defer内部",即主调函数退出时,error名称为算数不合法"}//定义除法运算函数***这里与本文中第一幕①error接口的例子不同func Devide(num1,。
相关热词: Go语言
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/jiaob/go/9845.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
Lisp进修Windows下面的开拓情
时间:2021-01-12
-
Lisp进修Windows下面的开拓情
时间:2021-01-12
-
为Go语言GC正名-2秒到1毫
时间:2020-12-27
-
go语言初探 一个helloworld编
时间:2020-12-27
热门文章
-
为Go语言GC正名-2秒到1毫秒的演变史
时间:2020-12-27
-
Lisp进修Windows下面的开拓情况搭建
时间:2021-01-12
-
Lisp进修Windows下面的开拓情况搭建
时间:2021-01-12
-
go语言初探 一个helloworld编译出来有2.2M!
时间:2020-12-27
